/**
 * Authors:
 * Vladimír Matěna
 * Jan Skalický
 */
package inireader;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

/**
 * Class extending BuferedReader. Used for reading section from input stream.
 * section are read as list of lines belonging to them in configuration file.
 */
public class SectionReader extends BufferedReader
{
	List<String> streamData;
	ListIterator<String> lineIterator;

	/**
	 * Creates SectionReader.
	 * @param in Reader used as base
	 * @throws IOException
	 */
	SectionReader(Reader in) throws IOException
	{
		super(in);

		streamData = new ArrayList<String>();

		while (!atEnd())
		{
			streamData.add(readLine());
		}

		lineIterator = streamData.listIterator();
	}

	/**
	 * Check whenever end of input was reached.
	 * @return true if at end
	 * @throws IOException
	 */
	private boolean atEnd() throws IOException
	{
		mark(1);
		int next = read();
		reset();
		return next == -1;
	}

	/**
	 * Go back in input until nonblank and noncomment line is reached.
	 */
	private void replayTrailingWhitespaceOrComment()
	{
		while (lineIterator.hasPrevious())
		{
			// stop returning if section data has been found
			String previous = lineIterator.previous();
			if ((previous.trim().length() != 0)
					&& (!previous.trim().startsWith(Configurator.COMMENT)))
			{
				lineIterator.next();
				break;
			}
		}
	}

	/**
	 * Remove blank or comment lines from end of list iterator.
	 * @param list both-directional iterator pointing to end
	 */
	private void removeTrailingWhitespaceOrComment(List<String> list)
	{
		while (list.size() > 0)
		{
			// When something different from comment or whitespace is found
			// end skipping lines
			if((list.get(list.size() - 1).trim().length() > 0)
				&& !list.get(list.size() - 1).trim().startsWith(Configurator.COMMENT))
			{
				break;
			}
			
			list.remove(list.size() - 1);
		}
	}

	/**
	 * Reads section.
	 * @return List<String> containing lies of section as in file
	 * @throws IOException
	 */
	List<String> readSection() throws IOException
	{
		List<String> section = new ArrayList<String>();
		boolean inSection = false;

		// read lines belonging to section
		while (lineIterator.hasNext())
		{
			String currentLine = lineIterator.next();

			// beginning of next section found -> stop reading
			if (inSection && currentLine.startsWith(Configurator.SECTION_LEFT_BRACKET))
			{
				// undo one step - header should be read when readSection
				// is called again.
				lineIterator.previous();

				// undo reading all blan lines
				//	- those belong as comment to next section
				replayTrailingWhitespaceOrComment();

				break;
			}

			// beginning of current section was found
			if (currentLine.startsWith(Configurator.SECTION_LEFT_BRACKET))
			{
				inSection = true;
			}

			section.add(currentLine);
		}

		// removes blank lines from the end
		removeTrailingWhitespaceOrComment(section);

		if (!inSection)
		{
			section.clear();
		}

		return section;
	}
}
